with Ada.Text_IO; use Ada.Text_IO;

package body Projet_Types.Classement is

   ---------
   -- "<" --
   ---------

   function Inferieur (X, Y : Matiere; Selon : Criteres) return Boolean is
   begin
      for J in Selon'Range loop
         case Selon (J).Un_Champ is
            when Etat =>
               case Selon (J).Un_Ordre is
                  when Croissant =>
                     if X.Une_Note.Selon < Y.Une_Note.Selon then
                        return True;
                     elsif Y.Une_Note.Selon < X.Une_Note.Selon then
                        return False;
                     end if;
                  when Decroissant =>
                     if X.Une_Note.Selon < Y.Une_Note.Selon then
                        return False;
                     elsif Y.Une_Note.Selon < X.Une_Note.Selon then
                        return True;
                     end if;
               end case;
            when Coefficient =>
               case Selon (J).Un_Ordre is
                  when Croissant =>
                     if X.Un_Coefficient < Y.Un_Coefficient then
                        return True;
                     elsif Y.Un_Coefficient < X.Un_Coefficient then
                        return False;
                     end if;
                  when Decroissant =>
                     if X.Un_Coefficient < Y.Un_Coefficient then
                        return False;
                     elsif Y.Un_Coefficient < X.Un_Coefficient then
                        return True;
                     end if;
               end case;
            when Intitule =>
               case Selon (J).Un_Ordre is
                  when Croissant =>
                     if X.Un_Intitule < Y.Un_Intitule then
                        return True;
                     elsif Y.Un_Intitule < X.Un_Intitule then
                        return False;
                     end if;
                  when Decroissant =>
                     if X.Un_Intitule < Y.Un_Intitule then
                        return False;
                     elsif Y.Un_Intitule < X.Un_Intitule then
                        return True;
                     end if;
               end case;
            when Note =>
               case Selon (J).Un_Ordre is
                  when Croissant =>
                     if X.Une_Note.Selon = Libre then
                        if Y.Une_Note.Selon = Libre then
                           null;
                        else
                           return True;
                        end if;
                     elsif Y.Une_Note.Selon = Libre then
                        return False;
                     elsif X.Une_Note.Une_Valeur < Y.Une_Note.Une_Valeur then
                        return True;
                     elsif Y.Une_Note.Une_Valeur < X.Une_Note.Une_Valeur then
                        return False;
                     end if;
                  when Decroissant =>
                     if X.Une_Note.Selon = Libre then
                        if Y.Une_Note.Selon = Libre then
                           null;
                        else
                           return False;
                        end if;
                     elsif Y.Une_Note.Selon = Libre then
                        return True;
                     elsif X.Une_Note.Une_Valeur < Y.Une_Note.Une_Valeur then
                        return False;
                     elsif Y.Une_Note.Une_Valeur < X.Une_Note.Une_Valeur then
                        return True;
                     end if;
               end case;
         end case;
      end loop;
      return False;
   end Inferieur;

   -------------
   -- Classer --
   -------------

   procedure Classer (Selon : in Criteres; Des_Matieres : in out Matieres) is
      function "<" (X, Y : Matiere) return Boolean is
      begin return Inferieur  (X, Y, Selon); end;
      Une_Matiere : Matiere;
   begin
      for I in Des_Matieres'First .. Des_Matieres'Last -1 loop
         for J in reverse I + 1 .. Des_Matieres'Last loop
            if Des_Matieres (J) < Des_Matieres (J - 1) then
               Une_Matiere := Des_Matieres (J -1);
               Des_Matieres (J -1) := Des_Matieres (J);
               Des_Matieres (J) := Une_Matiere;
            end if;
         end loop;
      end loop;
   end Classer;

end Projet_Types.Classement;
